package cn.jiangjiesheng.bootstrap.gateway.commons;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.jiangjiesheng.bootstrap.commons.exception.BizzException;
import cn.jiangjiesheng.bootstrap.commons.exception.QpaasOperationException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by dev@jiangjiesheng.cn on 2021/9/26  <br/>
 *
 * @author dev@jiangjiesheng.cn
 */
@Component
@Slf4j
public class OkRequestService {

    @Autowired
    private OkHttpClient okHttpClient;

    @Autowired
    private DiscoveryClient discoveryClient;

    private final AtomicInteger requestCounter = new AtomicInteger(0);

    /**
     * 发起Get请求
     *
     * @param serviceName
     * @param path
     * @param queryParams
     * @return
     */
    public JSONObject doGet(String serviceName, String path, Map<String, Object> queryParams) {
        int requestIndex = requestCounter.incrementAndGet();
        int serviceCount = discoveryClient.getInstances(serviceName).size();
        if (serviceCount <= 0) {
            throw new BizzException(String.format("service '%s' has no instance.", serviceName));
        }
        JSONObject returning = null;
        ServiceInstance instance = discoveryClient.getInstances(serviceName).get(requestIndex % serviceCount);
        HttpUrl.Builder httpUrlBuilder = new HttpUrl.Builder()
                .scheme(Objects.isNull(instance.getScheme()) ? "http" : instance.getScheme())
                .host(instance.getHost())
                .port(instance.getPort())
                .addPathSegments(StringUtils.stripStart(path, "/"));
        queryParams.forEach((key, value) -> {
            httpUrlBuilder.addQueryParameter(key, value.toString());
        });
        HttpUrl httpUrl = httpUrlBuilder.build();
        Request request = new Request.Builder()
                .url(httpUrl)
                .get()
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Objects.requireNonNull(response.body());
        try {
            String bodyString = response.body().string();
            log.debug("doGet to {}, returning {}", httpUrl.url(), bodyString);
            returning = JSON.parseObject(bodyString);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!returning.getBoolean("success")) {
            throw new QpaasOperationException(returning.getString("message"));
        }
        return returning;
    }
}
